package com.espirit.eap.manager;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import com.espirit.eap.sa.Website;
import com.googlecode.cswish.struts.ContextHolder;
import com.googlecode.cswish.struts.IAsync;
import com.googlecode.cswish.struts.Initialization;
import com.googlecode.cswish.struts.hibernate.DbTools;
import com.googlecode.cswish.struts.spring.Executor;
import com.googlecode.cswish.struts.spring.GenericService;
import com.googlecode.cswish.struts.spring.ObjectFactory;
import com.googlecode.cswish.struts.spring.SystemEnv;

@Service
@Lazy(value=false)
public class TaskSchedulerStartupService implements Initialization, IAsync {
	
	private static final Log logger = LogFactory.getLog(TaskSchedulerStartupService.class);
	
	@Resource
    private ObjectFactory objectFactory;
	
	@Resource
	private TaskSchedulerService taskSchedulerService;
	
	@Resource
	private GenericService genericService;
	
	@Resource
	DBAManager dbaManager;
	
	@Override
	public String[] getProductName() {
		return Website.DEFAULT_NAMES;
	}
	
	@PostConstruct
	private void init() {
		boolean isJunit = "true".equals(System.getProperty(SystemEnv.JUNIT_TEST));
		
		boolean ready = DbTools.getInstance().dbIsReady(null);
		if (!ready){
			dbaManager.initDB("create-drop");
			
			dbaManager.createSaasSite();
		} else {
			boolean autoUpdate = !"false".equals(System.getProperty("hibernate.db.update"));
			if (autoUpdate){
				dbaManager.initDB("update");
			}
		}
		
		if (!isJunit) {
			// check and init the session check job
			checkAndAddTaskScheduler("Clean Invalid Login User",
					"com.googlecode.cswish.security.SafeManager.cleanInvalidLoginUser",
					"3600000", "每隔1小时");
		}
		
	}
	
	private void checkAndAddTaskScheduler(String name, String command, String cond, String desc) {
		genericService.executeInSite(Website.DEFAULT_NAME, new Executor<String, String[]>() {
			@Override
			public String execute(String[] parameters) {
				String name = parameters[0];
				String command = parameters[1];
				String cond = parameters[2];
				String desc = parameters[3];
				TaskScheduler example = new TaskScheduler();
				example.setName(name);
				TaskScheduler taskScheduler = genericService.searchAll(example).getData(0);
				if (taskScheduler == null) {
					taskScheduler = example;
				}
				
				taskScheduler.setCommand(command);
				taskScheduler.setCond(cond);
				taskScheduler.setActive(true);
				taskScheduler.setDescription(desc);
				genericService.merge(taskScheduler);
				return null;
			}
		}, new String[] {name, command, cond, desc});
	}
	
	@Override
	public void initSite() {
		boolean isJunitTest = "true".equals(System.getProperty(SystemEnv.JUNIT_TEST));
		if (isJunitTest) {
			return ;
		}
		
		IAsync asyncStartup = (IAsync)objectFactory.getBean(TaskSchedulerStartupService.class.getName(), true);
		String site = ContextHolder.get().getSiteName();
		asyncStartup.asyncExecute(site);
	}
	
	@Async
	public void asyncExecute(Object parameter) {
		String site = (String)parameter;
		
		TaskScheduler example = new TaskScheduler();
		example.setActive(true);
		List<TaskScheduler> data = genericService.searchAll(example).getData();
		for (TaskScheduler taskScheduler : data) {
			try {
				taskSchedulerService.runScheduler(taskScheduler, site);
			} catch (Exception ex) {
				logger.error("Run scheduler " + taskScheduler.getName(), ex);
			}
		}
	}
}